package brickdestroyer.simulation;

import brickdestroyer.math.Rectangle2D;
import brickdestroyer.math.Vector2D;
import java.awt.Graphics;

/**
 * This class represents a brick object in the game.
 * 
 * @author Momchil Atanasov
 */
public class Brick extends Rectangle2D {

    /**
     * This is the default width of the bricks.
     */
    public static final float DEFAULT_BRICK_WIDTH = 75.0f; //was 100

    /**
     * This is the default height of the bricks.
     */
    public static final float DEFAULT_BRICK_HEIGHT = 40.0f; //was 60

    /*
     * This object holds the type of the brick.
     * Such an object is used so that multiple
     * functionalities can be added without the need
     * of repeating code.
     */
    protected BrickType type = BrickType.ID_NONE;

    private final Simulation simulation;

    /**
     * Creates a brick object and places it at the given position.
     * @param simulation current simulation
     * @param x X coordinate of the brick
     * @param y Y coordinate of the brick
     */
    public Brick(Simulation simulation, float x, float y) {
        super(x, y, DEFAULT_BRICK_WIDTH, DEFAULT_BRICK_HEIGHT);
        this.simulation = simulation;
    }

    /**
     * Creates a brick object and places it at the given position
     * @param simulation current simulation
     * @param position position of the brick
     */
    public Brick(Simulation simulation, Vector2D position) {
        this(simulation, position.x, position.y);
    }

    /**
     * Sets a new type of the brick.
     * @param type new brick type
     */
    public final void setType(BrickType type) {
        this.type = type;
    }

    /**
     * Returns the type of this brick
     * @return this brick's type
     */
    public final BrickType getType() {
        return type;
    }

    /**
     * This method gets called when a collision with
     * this brick has occured in order for some event
     * to occur.
     * @param ball ball object that has hit the brick
     */
    public void onHit(Ball ball) {
        type.onHit(simulation, this, ball);
        type = type.demote();
    }

    /**
     * Determines if this brick is should be destroyed
     * in order for the player to win.
     * @return
     */
    public boolean needsToBeDestroyed() {
        return (type != null) ? type.needsToBeDestroyed() : false;
    }

    /**
     * This method destroyes this brick.
     */
    public void destroy() {
        type = BrickType.ID_NONE;
    }

    /**
     * This method checks if this brick has been destoryed.
     * @return <code>true</code> if the brick has been destoryed,
     * <code>false</code> otherwise.
     */
    public boolean isDestroyed() {
        return (type == BrickType.ID_NONE);
    }

    /**
     * This method displays the brick on the screen.
     * @param g interface to the graphics handle.
     */
    public void display(Graphics g) {
        if (type != null) {
            type.display(g, this);
        }
    }
    
}
